/* 利用 重写 实现的多态:
 * 1、父对象(父类)中声明的函数被子对象(子类)所重写
 * 2、将来在期望通过父对象(父类)的实例调用函数的地方，
 *    如果使用的是子对象(子类)的实例，则会调用子对象(子类)中重写后的函数
 */

class Animal {
    constructor(type) {
            this.type = type;
        }
        // 作为父类声明的eat函数是可以被子类所继承的
    eat() {
        console.log(this.type + '类动物');
    }
}

class Birds extends Animal {
    constructor(name) {
            super('禽');
            this.name = name;
        }
        // 子类重写了从父类中继承过来的eat函数
    eat() {
        console.log(`${this.type}类动物${this.name}开吃了`);
    }
}

class Beast extends Animal {
    constructor(name) {
            super('兽');
            this.name = name;
        }
        // 子类重写了从父类中继承过来的eat函数
    eat() {
        console.log(`${this.type}类动物${this.name}开吃了`);
    }
}

let b = new Birds('麻雀');
// b.eat();

let t = new Beast('熊二');
// t.eat();

// 这里将 feed 函数当作普通函数来对待
function feed(a) {
    // 使用 instanceof 关键字可以判断 a 是否是 Animal 类型
    // 判断 a 变量引用的实例 是否是 Animal 对象的实例 (这是不严谨的)
    if (a instanceof Animal) {
        a.eat(); // 这里的eat到底执行的是哪个eat取决于引用变量a指向哪个实例
    }
}

feed(b);

feed(t);